package com.jadows.tdog.state;

import cn.hutool.core.collection.CollUtil;
import com.jadows.tdog.dto.UserInfo;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * websocket 状态管理
 *
 * @author taojiacheng
 */
@Slf4j
public class SimpleWSSessionUtil {

    /**
     * uid 与 channel 的映射
     */
    private static final Map<String, Set<Channel>> UID_CHANNEL_MAPPING = new ConcurrentHashMap<>();
    private static final Map<Channel, UserInfo> CHANNEL_UID_MAPPING = new ConcurrentHashMap<>();


    /**
     * 根据 uid 获取 channel
     *
     * @param uid uid
     * @return Channel
     */
    public static Set<Channel> getChannelByUid(String uid) {
        return UID_CHANNEL_MAPPING.get(uid);
    }

    /**
     * 是否在当前服务器
     *
     * @param uid uid
     * @return boolean
     */
    public static boolean isCurrentServer(String uid) {
        // return UID_CHANNEL_MAPPING.containsKey(uid);
        Set<Channel> channels = UID_CHANNEL_MAPPING.get(uid);
        return !CollUtil.isEmpty(channels);
    }

    /**
     * 添加 uid 与 channel 的映射
     *
     * @param userInfo 用户信息
     * @param channel  channel
     */
    public static void addUidChannelMapping(UserInfo userInfo, Channel... channel) {
        for (Channel ch : channel) {
            log.info("添加channel: {}, 用户Id: {}", ch, userInfo.getMemberId());
            UID_CHANNEL_MAPPING.computeIfAbsent(userInfo.getMemberId(), k -> ConcurrentHashMap.newKeySet()).add(ch);
            CHANNEL_UID_MAPPING.put(ch, userInfo);
        }
    }

    /**
     * 移除 uid 与 channel 的映射
     */
    public static void removeUidChannelMapping(Channel channel) {
        log.info("移除channel: {}", channel);
        UserInfo userInfo = CHANNEL_UID_MAPPING.remove(channel);
        if (userInfo == null) {
            log.warn("用户信息为空");
            return;
        }
        Set<Channel> channels = UID_CHANNEL_MAPPING.get(userInfo.getMemberId());
        if (channels != null) {
            channels.remove(channel);
            log.info("移除用户: {} 的channel: {}", userInfo.getMemberId(), channel);
            log.info("用户: {} 还有 {} 个channel", userInfo.getMemberId(), channels.size());
        }
    }

    /**
     * 获取 用户信息
     */
    public static UserInfo getUserDto(Channel channel) {
        return CHANNEL_UID_MAPPING.get(channel);
    }

}
